/********************************************************************************
 * Copyright (c) 2019 [Open Lowcode SAS](https://openlowcode.com/)
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0 .
 *
 * SPDX-License-Identifier: EPL-2.0
 ********************************************************************************/

package org.openlowcode.server.data.properties;

import java.util.ArrayList;
import java.util.logging.Logger;

import org.openlowcode.module.system.data.choice.ApplocaleChoiceDefinition;
import org.openlowcode.server.data.ChoiceValue;
import org.openlowcode.server.data.DataObject;
import org.openlowcode.server.data.DataObjectDefinition;
import org.openlowcode.server.data.DataObjectElement;
import org.openlowcode.server.data.DataObjectPayload;
import org.openlowcode.server.data.DataObjectPropertyDefinition;
import org.openlowcode.server.data.DisplayProfile;
import org.openlowcode.server.data.PropertyExtractor;
import org.openlowcode.server.data.loader.FlatFileLoaderColumn;
import org.openlowcode.server.data.properties.constraints.LinkedToDefaultParent;
import org.openlowcode.server.data.specificstorage.ExternalFieldSchema;
import org.openlowcode.server.data.storage.QueryCondition;
import org.openlowcode.server.data.storage.StoredTableIndex;
import org.openlowcode.server.data.storage.StringStoredField;

/**
 * A property to have on a transient object a parent. This is not persisted
 * 
 * @author <a href="https://openlowcode.com/" rel="nofollow">Open Lowcode
 *         SAS</a>
 *
 * @param <E> current data object
 * @param <F> the transient parent
 */
public class TransientparentDefinition<E extends DataObject<E>, F extends DataObject<F> & UniqueidentifiedInterface<F>>
		extends DataObjectPropertyDefinition<E> {
	@SuppressWarnings("unused")
	private static Logger logger = Logger.getLogger(LinkedtoparentDefinition.class.getName());
	private DataObjectDefinition<F> referenceobjectdefinition;
	private UniqueidentifiedDefinition<F> uniqueidentifiedforparentobjectforlink;

	private StringStoredField id;
	@SuppressWarnings("unused")
	private DisplayProfile<E> displayprofilehideparentfields;

	private LinkedToDefaultParent<E, F> linkedtodefaultparentrule;

	public DataObjectDefinition<F> getReferenceObjectDefinition() {
		return this.referenceobjectdefinition;
	}

	public void addLinkedToDefaultParentRule(LinkedToDefaultParent<E, F> linkedtodefaultparentrule) {
		this.linkedtodefaultparentrule = linkedtodefaultparentrule;
	}

	public LinkedToDefaultParent<E, F> getLinkedToDefaultParentRule() {
		return this.linkedtodefaultparentrule;
	}

	public TransientparentDefinition(DataObjectDefinition<E> parentobject, String name,
			DataObjectDefinition<F> referenceobjectdefinition) {
		super(parentobject, name);
		this.referenceobjectdefinition = referenceobjectdefinition;
		id = new StringStoredField(this.getName() + "ID", null, 200);
		this.addFieldSchema(id);
		// remove prefix LINKEDTOPARENTFOR
		StoredTableIndex parentidindex = new StoredTableIndex(this.getName().substring(17) + "PRID");
		parentidindex.addStoredFieldSchema(id);
		this.addIndex(parentidindex);

		this.displayprofilehideparentfields = parentobject.getDisplayProfileByName("HIDE" + name);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public DataObjectElement initiateFieldInstance(DataObjectPayload parentpayload) {
		return new Transientparent<E, F>(this, parentpayload, referenceobjectdefinition);
	}

	@Override
	public ArrayList<ExternalFieldSchema<?>> generateExternalSchema() {
		ArrayList<ExternalFieldSchema<?>> externalfieldlist = new ArrayList<ExternalFieldSchema<?>>();

		return externalfieldlist;

	}

	@Override
	public FieldSchemaForDisplay<E>[] setFieldSchemaToDisplay() {
		@SuppressWarnings("unchecked")
		FieldSchemaForDisplay<E>[] returnvalue = new FieldSchemaForDisplay[1];
		returnvalue[0] = new FieldSchemaForDisplay<E>("Parent " + this.getName() + " Id",
				"the technical id generated by the system of the parent", id, false, true, -60, 25, this.parentobject);
		return returnvalue;
	}

	public UniqueidentifiedDefinition<F> getGenericsParentobjectforlinkProperty() {
		return this.uniqueidentifiedforparentobjectforlink;
	}

	public void setGenericsParentobjectforlinkProperty(
			UniqueidentifiedDefinition<F> uniqueidentifiedforparentobjectforlink) {
		this.uniqueidentifiedforparentobjectforlink = uniqueidentifiedforparentobjectforlink;

	}

	@Override
	public QueryCondition getUniversalQueryCondition(String alias) {

		return null;
	}

	@Override
	public FlatFileLoaderColumn<E> getFlatFileLoaderColumn(DataObjectDefinition<E> objectdefinition,
			String[] columnattributes, PropertyExtractor<E> propertyextractor,
			ChoiceValue<ApplocaleChoiceDefinition> locale) {
		return null;
	}

	@Override
	public String[] getLoaderFieldList() {

		return new String[] {};

	}

	@Override
	public String[] getLoaderFieldSample(String name) {
		return new String[] {};
	}

}
